// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 



using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using svs.Mobile.BeyondScheduler.Core.Objects;
using svs.Mobile.BeyondScheduler.UI.Properties;

namespace svs.Mobile.BeyondScheduler.UI
{
	/// <summary>
	/// Provide a 2 line listview
	/// </summary>
	internal class TaskView : OwnerDrawnList
	{
		protected const int Column1Left = 5;
		protected const int Column2Left = 25;
		protected const int FONT_SIZE = 10;
		
		#region Constructors

		public TaskView()
		{
			// We need a total of 5 rows, so the height is 180/5=36
			Graphics g = CreateGraphics();
			Font font = new Font(Font.Name, FONT_SIZE, FontStyle.Bold);
			// Calc line height to be height of letter A plus 10%
			int fontHeight = (int) (g.MeasureString("A", font).Height*1.1);
			ItemHeight = fontHeight*2;
			g.Dispose();
			font.Dispose();
		}

		#endregion

		#region Public Properties

		/// <summary>
		/// Gets the selected Action.
		/// </summary>
		/// <value>The selected Action.</value>
		public ScheduledTask SelectedTask
		{
			get
			{
				if (SelectedIndex >= 0 && SelectedIndex < Items.Count)
					return Items[SelectedIndex] as ScheduledTask;
				else
					return null;
			}

			set
			{
				int index = -1;

				if (Items.Count > 0)
				{
					if (value != null)
					{
						index = Items.IndexOf(value);
					}

					if (index == -1)
						index = 0;
				}
				SelectedIndex = index;
				EnsureVisible(SelectedIndex);
			}
		}

		public override string OnEmptyText
		{
			get
			{
				return "There are no Scheduled Tasks!";
			}
		}

		#endregion

		#region Public Methods

		public void OnBeforeActivate()
		{
			//Do nothing
		}

		public void Clear()
		{
			Items.Clear();
			SelectedIndex = -1;
			Refresh();
		}

		public void Reload()
		{
			Items.Clear();
			Items.AddRange(TaskRepository.ScheduledTasks);

			if (Items.Count > 0)
			{
				if (SelectedIndex >= 0 && SelectedIndex < Items.Count)
					SelectedTask = Items[SelectedIndex] as ScheduledTask;
				else if (SelectedIndex >= Items.Count)
					SelectedTask = Items[Items.Count - 1] as ScheduledTask;
				else
					SelectedTask = Items[0] as ScheduledTask;
			}
			else
				SelectedTask = null;

			OnResize(null);
		}

		#endregion

		#region Protected Methods

		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);

			Rectangle r = ClientRectangle;

			r.Inflate(-20, -25);
		}

		protected override string GetItemText(int ItemIndex)
		{
			ScheduledTask f = Items[ItemIndex] as ScheduledTask;
			if (f != null)
				return f.Operation.Name;

			return string.Empty;
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			switch (e.KeyCode)
			{
				case Keys.Return:
					if (Select != null && SelectedIndex != -1)
					{
						Select(SelectedTask);
					}

					break;
			}

			if (!e.Handled)
			{
				base.OnKeyDown(e);
			}
		}

		/// <summary>
		/// Custom OnPaint. This paints the listview items
		/// </summary>
		/// <param name="e"></param>
		protected override void OnPaint(PaintEventArgs e)
		{
			// Declare vars
			Color fontColor;
			Bitmap bmp;

			// Get graphics object from bitmap.
			using (Graphics gOffScreen = Graphics.FromImage(OffScreen))
			{
				// Set background color
				gOffScreen.Clear(BackColor);

				// Set the y pos of the current item
				int itemTop = 0;

				// Draw the visible items.
				for (int n = VScrollBar.Value; n <= VScrollBar.Value + DrawCount; n++)
				{
					if (Items.Count == 0 || n > Items.Count - 1)
						break;

					// Get the current MailItem
					ScheduledTask Action = (ScheduledTask) Items[n];

					Rectangle itemArea;
					itemArea = new Rectangle(0,
					                         itemTop,
					                         ClientSize.Width - (VScrollBar.Visible ? VScrollBar.Width : 0),
					                         ItemHeight);
					itemArea.Inflate(-1, -1);
					itemArea.Width -= 1;


					Color itemColor = Action.Active ? ForeColor : Color.Gray;

					// Draw the selected item to appear highlighted
					if (n == SelectedIndex)
					{
						UIHelper.DrawRoundedPercentRectangle(gOffScreen,
						                                     new Pen(ForeColor),
						                                     SystemColors.Highlight,
						                                     SystemColors.Highlight,
						                                     itemArea, new Size(1, 1), 0);
						fontColor = CalcTextColor(itemColor);
					}
					else
					{
						fontColor = itemColor;
					}

					bmp = Action.Active ? Resources.TimerSmall : Resources.TimerSmallDisabled;

					ImageAttributes ia = new ImageAttributes();
					ia.SetColorKey(Color.Black, Color.Black);
					Rectangle imgRect = new Rectangle(Column1Left, itemTop + 3, bmp.Width, bmp.Height);
					gOffScreen.DrawImage(bmp, imgRect, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, ia);

					//Draw the name of the Action
					using (Font fontMainItem = new Font(Font.Name, FONT_SIZE, Action.Event.ExistOnDevice ? FontStyle.Bold : FontStyle.Regular))
					{
						Rectangle nameRect = new Rectangle(Column2Left, itemTop, itemArea.Width - Column2Left, ItemHeight);

						string name =
							string.Format("{0}{1}",
							              Action.Event.StartTime.HasValue
							              	? ((DateTime) Action.Event.StartTime).ToShortTimeString() + " - "
							              	: String.Empty, Action.Operation != null ? Action.Operation.Name : "<No Operation>");
						if (Width <= 240 && name.Length > 35)
							name = name.Substring(0, 35) + "...";
						else if (Width > 240 && name.Length > 60)
							name = name.Substring(0, 60) + "...";

						using (Brush b = new SolidBrush(fontColor))
						{
							gOffScreen.DrawString(name, fontMainItem, b, nameRect);
						}

						// Draw the number of ScheduledTasks/tracks
						StringFormat sf = new StringFormat();
						sf.Alignment = StringAlignment.Far;
						sf.LineAlignment = StringAlignment.Far;
						itemArea.Inflate(-6, -2);

						using (Font fontNumber = new Font(Font.Name, FONT_SIZE - 2, FontStyle.Regular))
						{
							string InfoText =
								string.Format("Next Run: {0}",
								              Action.Event.ActualStartTime.HasValue
								              	? ((DateTime) Action.Event.ActualStartTime).ToString("h:mm tt on MMM dd")
								              	: "Never");

							using (Brush b = new SolidBrush(fontColor))
							{
								gOffScreen.DrawString(InfoText, fontNumber, b, itemArea, sf);
							}
						}
					}

					// Set the next item top to move down the item height
					itemTop += ItemHeight;
				}

				// Now draw the visible list box
				e.Graphics.DrawImage(OffScreen, 0, 0);
			}

			base.OnPaint(e);
		}

		protected override void OnPaintBackground(PaintEventArgs e)
		{
			
		}

		#endregion

		public delegate void SelectEvent(ScheduledTask action);
		public event SelectEvent Select;
	}
}